package com.hna.eking.AirlineServer.Service;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hna.eking.AirlineServer.Exception.RunServiceException;
import com.hna.eking.AirlineServer.Mapper.AirportInfo;
import com.hna.eking.AirlineServer.Mapper.AirportInfoMapper;
import com.hna.eking.AirlineServer.Mapper.MapInfo;
import com.hna.eking.AirlineServer.Mapper.MapInfoMapper;
import com.hna.eking.AirlineServer.Platform.MapInfo.MapInfoController;
import com.hna.eking.AirlineServer.Utils.FileUtils;

/**
 *
 * 航图表的控制类 Date : 2018-9-11 Description: 关于航图表的维护类 Copyright: Copyright &copy;
 * 2018 Company :aivac
 * 
 * @author APP BD lele
 * @version V1.0 修改历史 序号 日期 修改人 修改原因 1
 * 
 */
@Service
public class MapInfoService {
	private Logger logger = LoggerFactory.getLogger(MapInfoService.class);
	@Autowired
	private MapInfoMapper mapinfomapper;
	@Autowired
	private AirportInfoMapper airportmapper;
	@Value("${visualcharts.file.uploadpath}")
	private String MapFilePath;
	@Value("${visualcharts.state.enable}")
	private String ROW_STATUS_ENABLE;
	@Autowired
	private FileUtils fileServ;
	@Value("${visualcharts.state.area}")
	private String AREA_TYPE;

	/*
	 * 更新航图表内容，并更新机场表航图版本 参数： 航图信息：mapinfo 上传文件 upfile 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void MapInfoUpdate(MapInfo mapinfo, MultipartFile file) throws RunServiceException {
		String fileName = null;
		try {

			Date SysDate = new Date();
			String airportCode = mapinfo.getAirportCode();
			String User = mapinfo.getUpdateUser();

			/* 更新用户不能为空，否则失败 */
			if (User == null || "".equals(User)) {
				logger.error("update user can not be null");
				throw new RunServiceException(RunServiceException.UNKONW_USER);
			}

			String FileName = null;
			// MapInfo orgInfo = null;
			/* 获取原始航图类型 */
			MapInfo orgInfo = mapinfomapper.selectByAirportcodeAndMapcode(airportCode, mapinfo.getMapCode());
			if (orgInfo == null) {
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND, "airportcode is not found");
			}

			if (file != null) {
				FileName = fileServ.GenUploadFileName(airportCode, mapinfo.getMapType(), file.getOriginalFilename());
				mapinfo.setFilePath(FileName);
			} else {
				mapinfo.setFilePath(orgInfo.getFilePath());
			}

			/* 不支持修改区域图信息 */
			if (AREA_TYPE.equals(mapinfo.getMapType()) || AREA_TYPE.equals(orgInfo.getMapType())) {
				logger.error("this service can not update map which type is area ");
				throw new RunServiceException(RunServiceException.UNSPT_MAP_TYPE);
			}

			/* 更新航图信息表 */
			mapinfo.setEffectFlag(orgInfo.getEffectFlag()); //将有效标志置回去
			mapinfo.setUpdateDate(SysDate);
			mapinfo.setUpdateUser(User);
			int retnum = mapinfomapper.UpdateMapInfo(mapinfo);
			logger.debug("retnum" + retnum);
			if (retnum == 0) {
				logger.error("update table t_map_info row is 0");
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND,
						String.format("[mapcode:%s]", mapinfo.getMapCode()));
			}
			/* 更新机场信息表航图版本字段 */
			retnum = airportmapper.updateAirportMapVersion(airportCode, SysDate, User);
			if (retnum == 0) {
				logger.error("update table t_airport_info map version row is 0");
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND,
						String.format("[airportCode:%s]", airportCode));
			}

			/* 如果文件不为空 则上传新航图 */

			if (file != null) {
				/* 上传航图 */
				fileServ.UploadFile(FileName, file);

				/* 如果上传新文件，删除旧文件 */
				this.fileServ.delete(orgInfo.getFilePath());
			}

		} catch(DuplicateKeyException ex) {
			logger.error("unique error");
			ex.printStackTrace();
			throw new RunServiceException(RunServiceException.UNIQUE_ERROR);
		} catch (DataAccessException e) {
			logger.error("database error");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		} catch (IllegalStateException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.FILE_UPLOAD_FAIL);
		}
	}

	/*
	 * 更新航图表内容，支持区域图，并更新机场表航图版本 根据参数更新，文件更新路径 参数： 航图信息：mapinfo
	 * 
	 * 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void MapInfoUpdate(MapInfo mapinfo) throws RunServiceException {
		String fileName = null;
		try {

			Date SysDate = new Date();
			String airportCode = mapinfo.getAirportCode();
			String User = mapinfo.getUpdateUser();

			/* 更新用户不能为空，否则失败 */
			if (User == null || "".equals(User)) {
				logger.error("update user can not be null");
				throw new RunServiceException(RunServiceException.UNKONW_USER);
			}

			String FileName = null;
			// MapInfo orgInfo = null;
			/* 获取原始航图类型 */
			// MapInfo orgInfo = mapinfomapper.selectByAirportcodeAndMapcode(airportCode,
			// mapinfo.getMapCode());
			// mapinfo.setFilePath(orgInfo.getFilePath());

			/* 更新航图信息表 */
			mapinfo.setUpdateDate(SysDate);
			mapinfo.setUpdateUser(User);
			int retnum = mapinfomapper.UpdateMapInfo(mapinfo);
			logger.debug("retnum" + retnum);
			if (retnum == 0) {
				logger.error("update table t_map_info row is 0");
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND,
						String.format("[mapcode:%s]", mapinfo.getMapCode()));
			}
			/* 更新机场信息表航图版本字段 */
			retnum = airportmapper.updateAirportMapVersion(airportCode, SysDate, User);
			if (retnum == 0) {
				logger.error("update table t_airport_info map version row is 0");
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND,
						String.format("[airportCode:%s]", airportCode));
			}

		} catch(DuplicateKeyException ex) {
			logger.error("unique error");
			ex.printStackTrace();
			throw new RunServiceException(RunServiceException.UNIQUE_ERROR);
		} catch (DataAccessException e) {
			logger.error("database error");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}
	}
	/*
	 * 查询指定页航图信息 参数： 机场代码：airportcode 航图名称：mapname 模糊匹配 航图类型：maptype 返回条数：limit
	 * 跳过条数：offset 返回： 航图信息列表 {count：查询总条数，maplist:[航图列表]}
	 *
	 */

	public Map<String, Object> mapInfoListByInput(String airportcode, String mapname, String maptype, int limit,
			int offset) throws RunServiceException {
		Map<String, Object> map = new HashMap<String, Object>();

		try {
			/* 查询所有记录条数 */
			int Count = mapinfomapper.getCountByInput(airportcode, mapname, maptype);
			if (Count == 0) {
				logger.warn("select map info row is 0");
				throw new RunServiceException(RunServiceException.DATA_NOT_FOUND);
			}
			List<MapInfo> mapinfolist = mapinfomapper.selectListByInput(airportcode, mapname, maptype, limit, offset);
			map.put("count", Count);
			map.put("maplist", mapinfolist);
		} catch (DataAccessException e) {
			logger.error("database error");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}

		return map;
	}

	/*
	 * 查询指定页航图信息 参数： 机场代码：airportcode 航图名称：mapcode 返回条数：limit 跳过条数：offset 返回： 航图信息列表
	 * {count：查询总条数，maplist:[航图列表]}
	 *
	 */

	public Map<String, Object> mapInfoAreaByInput(String airportcode, String mapcode, int limit, int offset)
			throws RunServiceException {
		Map<String, Object> map = new HashMap<String, Object>();

		try {
			/* 查询所有记录条数 */
			int Count = mapinfomapper.MapinfoAreaCountByInput(airportcode, mapcode);
			if (Count == 0) {
				logger.warn("select map info row is 0");
				throw new RunServiceException(RunServiceException.DATA_NOT_FOUND);
			}
			List<MapInfo> mapinfolist = mapinfomapper.MapinfoSelectAreaByInput(airportcode, mapcode, limit, offset);
			map.put("count", Count);
			map.put("maplist", mapinfolist);
		} catch (DataAccessException e) {
			logger.error("database error");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}

		return map;
	}

	/*
	 * 插入指定页航图信息 参数： 航图信息：mapinfo
	 * 
	 * 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void MapInfoInsert(MapInfo mapinfo, MultipartFile file) throws RunServiceException {
		String fileName = null;
		try {
			/* 如果文件为空 则失败 */
			if (file == null) {
				throw new RunServiceException(RunServiceException.FILE_UPLOAD_NULL);
			}

			/* 获取机场代码及插入用户 */
			String airportCode = mapinfo.getAirportCode();
			// String User = mapinfo.getCreateUser();

			/* 生成航图文件名 */
			fileName = fileServ.GenUploadFileName(airportCode, mapinfo.getMapType(), file.getOriginalFilename());

			/*查询当前最大的航图版本*/
			//AirportInfo airinfo = airportmapper.selectByArptNo(airportCode);
			/* 计算最大mapcode 加一为新的mapcode */
			int MaxCode = mapinfomapper.selectMaxMapCode(airportCode);
			mapinfo.setMapCode(String.format("%s%04d", airportCode, MaxCode + 1));
			//mapinfo.setMapVersion(airinfo.getMapVersion() + 1);
			mapinfo.setFilePath(fileName);

			
			/* 新增航图记录 */
			MapInfoInsert(mapinfo);

			
			/* 上传航图 */
			fileServ.UploadFile(fileName, file);
			

		}catch(DuplicateKeyException ex) {
			logger.error("unique error");
			ex.printStackTrace();
			throw new RunServiceException(RunServiceException.UNIQUE_ERROR);
		}catch (IllegalStateException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.FILE_UPLOAD_FAIL);
		}catch (DataAccessException e) {
			logger.error("database error");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}
	}

	/*
	 * 插入指定页航图信息 参数： 航图信息：mapinfo
	 * 
	 * 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void MapInfoInsert(MapInfo mapinfo) throws RunServiceException {
		String fileName = null;
		try {
			/* 获取日期 */
			Date SysDate = new Date();

			/* 获取机场代码及插入用户 */
			String airportCode = mapinfo.getAirportCode();
			String User = mapinfo.getCreateUser();

			mapinfo.setEffectFlag(ROW_STATUS_ENABLE);
			mapinfo.setCreateDate(SysDate);
			mapinfo.setUpdateDate(SysDate);
			mapinfo.setUpdateUser(User);
			// mapinfo.setMapVersion(SysDate);
			mapinfo.setEffectFlag(ROW_STATUS_ENABLE);
			Map<String, Object> map = new HashMap<String, Object>();
			String ret = null;

			/* 更新用户不能为空，否则失败 */
			if (User == null || "".equals(User)) {
				logger.error("create user can not be null");
				throw new RunServiceException(RunServiceException.UNKONW_USER);
			}

			/*查询当前最大的航图版本*/
			AirportInfo airinfo = airportmapper.selectByArptNo(airportCode);
			
			/* 插入信息 */
			mapinfo.setMapVersion(airinfo.getMapVersion() + 1);
			mapinfomapper.InsertMapInfo(mapinfo);

			/* 更新机场信息表航图版本字段 */
			int retnum = airportmapper.updateAirportMapVersion(airportCode, SysDate, User);
			if (retnum == 0) {
				logger.error("update table t_airport_info map version row is 0");
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND,
						String.format("[airportCode:%s]", airportCode));
			}

		} catch (DuplicateKeyException ex) {
			logger.error("unique error");
			ex.printStackTrace();
			throw new RunServiceException(RunServiceException.UNIQUE_ERROR);
		} catch (DataAccessException e) {
			logger.error("database error");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}
	}

	/*
	 * 逻辑删除指定页航图信息 参数： 机场代码：airportcode 航图代码：mapcode
	 * 
	 * 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void DeleteMapInfo(String airportcode, String mapcode, String User) throws RunServiceException {
		try {
			DeleteMapInfo(airportcode, mapcode, User, true);
		} catch (DataAccessException e) {
			logger.error("database errorl");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}
	}

	/*
	 * 逻辑删除指定页航图信息 参数： 机场代码：airportcode 航图代码：mapcode 是否删除文件 DelFlag true-删除
	 * false-不删除 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void DeleteMapInfo(String airportcode, String mapcode, String User, boolean DelFlag)
			throws RunServiceException {
		try {
			Date SysDate = new Date();

			/* 更新用户不能为空，否则失败 */
			if (User == null || "".equals(User)) {
				logger.error("create user can not be null");
				throw new RunServiceException(RunServiceException.UNKONW_USER);
			}

			/* 查询原始记录 */
			MapInfo orgInfo = null;
			if (DelFlag) {
				orgInfo = mapinfomapper.selectByAirportcodeAndMapcode(airportcode, mapcode);
				if (orgInfo == null) {
					logger.error("selectByAirportcodeAndMapcode table t_airport_info map version row is 0");
					throw new RunServiceException(RunServiceException.DATA_NOT_FOUND);

				}
			}

			/* 删除记录 */
			mapinfomapper.DeleteMapInfo(airportcode, mapcode, User, SysDate);

			/* 更新机场信息表航图版本字段 */
			int retnum = airportmapper.updateAirportMapVersion(airportcode, SysDate, User);
			if (retnum == 0) {
				logger.error("update table t_airport_info map version row is 0");
				throw new RunServiceException(RunServiceException.UPDATE_NOT_FOUND,
						String.format("[airportCode:%s]", airportcode));

			}

			/* 删除文件 分开查询、删除，避免数据库事物问题 */
			if (DelFlag) {
				fileServ.delete(orgInfo.getFilePath());
			}
		} catch (DataAccessException e) {
			logger.error("database errorl");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}
	}

	/*
	 * 逻辑删除指定机场所有航图信息 参数： 机场代码：airportcode 用户名：user
	 * 
	 * 返回： 无
	 *
	 */
	@Transactional(rollbackFor = RunServiceException.class)
	public void DeleteAllMapInfo(String airportcode, String User) throws RunServiceException {
		try {

			Date SysDate = new Date();

			/* 更新用户不能为空，否则失败 */
			if (User == null || "".equals(User)) {
				logger.error("create user can not be null");
				throw new RunServiceException(RunServiceException.UNKONW_USER);
			}
			/* 查询原始记录 */
			List<MapInfo> orgInfo = mapinfomapper.selectListByAirportCode(airportcode);

			/* 删除记录 */
			mapinfomapper.DeleteAllMapInfo(airportcode, User, SysDate);

			/* 删除所有文件除了区域图 分开查询、删除，避免数据库事物问题 */
			for (MapInfo info : orgInfo) {
				if (!AREA_TYPE.equals(info.getMapType())) {
					fileServ.delete(info.getFilePath());
				}
			}

		} catch (DataAccessException e) {
			logger.error("database errorl");
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.DATABASE_ERROR);
		}
	}

	/*
	 * 生成指定航图压缩包 参数： 机场代码：airportcode 用户名：user
	 * 
	 * 返回： 无
	 *
	 */
	public void generateMapZip(String airportCode, String User) {
		Date sysDate = new Date();
		List<MapInfo> list = mapinfomapper.selectListByAirportCode(airportCode);

		/* 更新用户不能为空，否则失败 */
		if (User == null || "".equals(User)) {
			logger.error("user can not be null");
			throw new RunServiceException(RunServiceException.UNKONW_USER);
		}

		/* 生成航图列表 */
		List<String> fileList = new ArrayList<String>();
		for (MapInfo info : list) {
			fileList.add(info.getFilePath());
		}

		/* 查询机场航图版本 */
		AirportInfo apInfo = airportmapper.selectByArptNo(airportCode);
		if (apInfo == null) {
			throw new RunServiceException(RunServiceException.DATA_NOT_FOUND);
		}

		/* 判断文件夹是否存在 */
		File fp = new File(String.format("%s/zip", MapFilePath, airportCode));
		if (!fp.exists()) {
			fp.mkdirs();
		}
		/* 生成压缩包 */
		String zipPath = String.format("%s/zip/%s_%08d.zip", MapFilePath, airportCode, apInfo.getMapVersion());
		try {
			fileServ.compressFile(fileList, zipPath);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RunServiceException(RunServiceException.ZIP_FILE_FAILED);
		}
	}
}
